/**
 * Copyright (c) 2014, Dallas.Cao 曹斌 (adffice@gmail.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.adffice.library.dbhelper.sqlite;

import android.content.ContentValues;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;

import com.adffice.library.dbhelper.table.Property;
import com.adffice.library.dbhelper.table.TableInfo;

import java.util.Collection;
import java.util.Date;

/**
 * Created by dallas on 14-4-20.
 */
public class SqlBuilder {

    /**
     * 构建创建表的sql语句。
     *
     * @param tableInfo 数据库表信息TableInfo对象
     * @return sql语句SqlInfo对象
     */
    public static SqlInfo buildCreateTableSql(TableInfo tableInfo) {
        if (tableInfo == null) {
            return null;
        }

        Property id = tableInfo.getId();

        StringBuilder strSQL = new StringBuilder();
        strSQL.append("CREATE TABLE IF NOT EXISTS ");
        strSQL.append(tableInfo.getTableName());
        strSQL.append(" ( ");

        Class<?> primaryClazz = id.getDataType();
        if (primaryClazz == int.class || primaryClazz == Integer.class
                || primaryClazz == long.class || primaryClazz == Long.class) {
            strSQL.append(id.getColumn()).append(" INTEGER PRIMARY KEY AUTOINCREMENT,");
        } else {
            strSQL.append(id.getColumn()).append(" TEXT PRIMARY KEY,");
        }

        Collection<Property> properties = tableInfo.propertyMap.values();
        for (Property property : properties) {
            strSQL.append(property.getColumn());
            Class<?> dataType = property.getDataType();
            if (dataType == int.class || dataType == Integer.class
                    || dataType == long.class || dataType == Long.class) {
                strSQL.append(" INTEGER");
            } else if (dataType == float.class || dataType == Float.class
                    || dataType == double.class || dataType == Double.class) {
                strSQL.append(" REAL");
            } else if (dataType == boolean.class || dataType == Boolean.class) {
                strSQL.append(" NUMERIC");
            }
            strSQL.append(",");
        }

        strSQL.deleteCharAt(strSQL.length() - 1);
        strSQL.append(" )");

        SqlInfo info = new SqlInfo();
        info.setSql(strSQL.toString());
        return info;

    }

    /**
     * 构建删除表的sql语句。
     *
     * @param tableInfo 数据库表信息TableInfo对象
     * @return sql语句SqlInfo对象
     */
    public static SqlInfo buildDropTableSql(TableInfo tableInfo) {
        if (tableInfo == null) {
            return null;
        }
        String sql = "DROP TABLE IF EXISTS " + tableInfo.getTableName();

        SqlInfo info = new SqlInfo();
        info.setSql(sql);
        return info;
    }

    /**
     * 构建查询sql语句
     */
    public static SqlInfo buildQuerySql(
            TableInfo tableInfo, boolean distinct, String[] columns, String where, String[] whereArgs,
            String groupBy, String having, String orderBy, String limit) {
        String sql = SQLiteQueryBuilder.buildQueryString(distinct, tableInfo.getTableName(), columns, where, groupBy, having, orderBy, limit);

        SqlInfo info = new SqlInfo();
        info.setSql(sql);
        info.setBindArgs(whereArgs);
        return info;
    }

    public static ContentValues buildContentValues(TableInfo tableInfo, Object entity) {
        Collection<Property> properties = tableInfo.propertyMap.values();
        ContentValues contentValues = new ContentValues();
        for (Property property : properties) {
            if (property.getDataType().equals(String.class)) {
                contentValues.put(property.getColumn(), (String) property.getValue(entity));
            } else if (property.getDataType().equals(Integer.class) || property.getDataType().equals(int.class)) {
                contentValues.put(property.getColumn(), (Integer) property.getValue(entity));
            } else if (property.getDataType().equals(Byte.class) || property.getDataType().equals(byte.class)) {
                contentValues.put(property.getColumn(), (Byte) property.getValue(entity));
            } else if (property.getDataType().equals(Long.class) || property.getDataType().equals(long.class)) {
                contentValues.put(property.getColumn(), (Long) property.getValue(entity));
            } else if (property.getDataType().equals(Double.class) || property.getDataType().equals(double.class)) {
                contentValues.put(property.getColumn(), (Double) property.getValue(entity));
            } else if (property.getDataType().equals(Float.class) || property.getDataType().equals(float.class)) {
                contentValues.put(property.getColumn(), (Float) property.getValue(entity));
            } else if (property.getDataType().equals(Short.class) || property.getDataType().equals(short.class)) {
                contentValues.put(property.getColumn(), (Short) property.getValue(entity));
            } else if (property.getDataType().equals(Byte[].class) || property.getDataType().equals(byte[].class)) {
                contentValues.put(property.getColumn(), (byte[]) property.getValue(entity));
            } else if (property.getDataType().equals(Character.class) || property.getDataType().equals(char.class)) {
                Character value = (Character) property.getValue(entity);
                contentValues.put(property.getColumn(), value + "");
            } else if (property.getDataType().equals(java.util.Date.class)) {
                Date value = (Date) property.getValue(entity);
                contentValues.put(property.getColumn(), value == null ? null : value.getTime());
            } else if (property.getDataType().equals(Boolean.class) || property.getDataType().equals(boolean.class)) {
                // 0 = false, 1 = true
                Boolean value = (Boolean) property.getValue(entity);
                contentValues.put(property.getColumn(), value ? 1 : 0);
            } else {
                Log.e("dbhelper", "nonsupport data type " + property.getDataType());
            }
        }
        return contentValues;
    }

}
